package com.mall.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mall.dao.CartMapper;
import com.mall.dao.SkuInfoDao;
import com.mall.entity.Cart;
import com.mall.entity.SkuInfo;
import com.mall.service.CartService;
import com.mall.utils.CookieUtil;
import com.mall.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.*;

@Service
@Slf4j
public class CartServiceImpl implements CartService {
    @Autowired
    private CartMapper cartMapper;
    @Autowired
    private SkuInfoDao skuInfoMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    //cookie中购物车的名字
    public static final String COOKIE_NAME = "cookie_message";

    /***
     * 将商品加入redis购物车中  如果存在则数量+1并同时更新价格
     * @return 返回true表示成功, false表示失败
     */
    public void addProductToCart(String productSkuId,String userId) {
        String key = "user:" + userId+ ":cart";
        String field = productSkuId;
        //查询商品价格
        QueryWrapper<SkuInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sku_id",productSkuId);
        SkuInfo skuInfo = skuInfoMapper.selectOne(queryWrapper);

        //首先从redis中读取
        Cart cart = JSONObject.parseObject((String) RedisUtil.getKeyFromHash(stringRedisTemplate,key,field),Cart.class);
        if(cart == null){//若为空就创建对象
            cart = new Cart();
            cart.setProductSkuId(Integer.valueOf(productSkuId));
            cart.setUserId(Long.parseLong(userId));
            //设置价格
            cart.setProductOldPrice(skuInfo.getPrice());
            cart.setDeleted(false);
            cart.setIsDown(false);
            cart.setCreateTime(new Date());
            cart.setProductNum(0);
        }
        //设置数量+1
        cart.setProductNum(cart.getProductNum()+1);
        //设置新的价格
        cart.setProductNewPrice(skuInfo.getPrice());
        log.info(String.valueOf(cart));
        RedisUtil.insertKeyToHash(stringRedisTemplate,key, field, JSON.toJSONString(cart));
    }

    /***
     * 从redis中读取用户的购物车信息
     * @return 读取到的是json字符串
     */
    public Map<String, String> getCartFromRedis(String userId) {
        //读取
        Map<String, String> cart = RedisUtil.getMapFromHash(stringRedisTemplate,"user:" + userId + ":cart");

        //判断redis中是否存在用户的购物车，如果不存在就从数据库中读取
        if (cart == null || cart.size() == 0) {//redis中不存在
            //读取数据库
            QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id", userId);
            queryWrapper.eq("deleted", 0);//当前购物车商品没有删除
            //查询用户所有的购物车信息
            List<Cart> cartList = cartMapper.selectList(queryWrapper);
            //首先将这些信息全部加入redis中
            String key = "user:" + userId + ":cart";
            Map<String, String> map = new HashMap<>();
            for (Cart c : cartList) {
                String field = c.getProductSkuId().toString();
                String value = JSON.toJSONString(c);
                map.put(field, value);
            }
            RedisUtil.insertMapToHash(stringRedisTemplate,key, map);

            cart = map;
        }
        return cart;
    }

    /***
     * 从redis中获取用户购物车中某个商品
     * @param userId
     * @param skuId
     * @return
     */
    public Cart getProductFromRedis(String userId, String skuId) {
        return JSONObject.parseObject((String) RedisUtil.getKeyFromHash(stringRedisTemplate,"user:" + userId + ":cart", skuId),Cart.class);
    }

    /***
     * 将cookie中的数据保存到redis中  当用户在未登录时向购物车加入了商品，登陆之后需要同步进去
     */
    public void saveCookieToRedis(HttpServletRequest request) {
        //从cookie中获取加入购物车的商品
        String cart_message = null;
        try {
            cart_message = CookieUtil.getCookie(request, COOKIE_NAME);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //使用fastjson将得到的json转为集合对象
        List<Cart> cartList = JSON.parseArray(cart_message, Cart.class);
        //将这个集合保存到redis中
    }

    /***
     * 当用户未登录的时候，将加入购物车的商品放入cookie中
     * @param request
     * @param response
     */
    public void saveProductToCookie(HttpServletRequest request, HttpServletResponse response, String skuId) {
        //从cookie中获取加入购物车的商品
        String cart_message = null;
        try {
            cart_message = CookieUtil.getCookie(request, COOKIE_NAME);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        List<Cart> cartList = null;
        //查询商品信息
        QueryWrapper<SkuInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sku_id",skuId);
        SkuInfo skuInfo = skuInfoMapper.selectOne(queryWrapper);
        //生成购物车对象
        Cart cart = new Cart();
        cart.setProductSkuId(Integer.valueOf(skuId));
        cart.setProductNum(1);
        cart.setProductOldPrice(skuInfo.getPrice());
        cart.setProductNewPrice(skuInfo.getPrice());
        cart.setDeleted(false);
        cart.setCreateTime(new Date());
        cart.setIsDown(false);
        if (cart_message == null || cart_message.equals("")) {//如果购物车不存在，或者购物车为空
            //创建一个购物车
            cartList = new ArrayList<>();
            //将当前商品加入购物车中
            cartList.add(cart);
        } else {//购物车存在
            //使用fastjson将得到的json转为集合对象
            cartList = JSON.parseArray(cart_message, Cart.class);
            boolean flag = false;//标识  是否存在该商品
            //判断该商品是否存在
            for (Cart c : cartList) {
                if(c.getProductSkuId() == Integer.valueOf(skuId)){
                    c.setProductNum(c.getProductNum()+1);
                    flag = true;
                    break;
                }
            }
            if(!flag){//如果商品不存在就直接添加
                //将当前商品加入购物车中
                cartList.add(cart);
            }
        }
        //将购物车加入cookie中
        try {
            CookieUtil.setCookie(response, COOKIE_NAME, JSON.toJSONString(cartList));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    /***
     * 从cookie中获取购物车
     * @param request
     * @return
     */
    public List<Object> getProductFromCookie(HttpServletRequest request){
        String cookie = null;
        try {
            cookie = CookieUtil.getCookie(request, COOKIE_NAME);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        List<Object> cartList = JSON.parseArray(cookie);
        return cartList;
    }

    /***
     * 从redis中删除一个商品 若商品数量大于1 则数量-1， 等于1 直接删除
     * @param userId
     * @param skuId
     */
    @Override
    public void deleteProductFromRedis(String userId, String skuId) {
        String key = "user:" + userId + ":cart";
        String cstr = (String) RedisUtil.getKeyFromHash(stringRedisTemplate,key, skuId);
        Cart cart = JSON.parseObject(cstr, Cart.class);
        if(cart.getProductNum() > 1){
            cart.setProductNum(cart.getProductNum()-1);
            RedisUtil.insertKeyToHash(stringRedisTemplate,key,skuId,JSON.toJSONString(cart));
        }else{
            //数量等于1直接删除
            RedisUtil.deleteProduct(stringRedisTemplate,key,skuId);
            //同时删除数据库中的值
            cart.setDeleted(true);
            QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user_id",cart.getUserId());
            queryWrapper.eq("product_sku_id",cart.getProductSkuId());
            int rows = cartMapper.update(cart,queryWrapper);
            if(rows == 1){
                log.info(cart.getId()+"删除成功");
            }else{
                log.info(cart.getId()+"删除成功");
            }
        }
    }

    /***
     * 从cookie中删除商品
     * @param skuId
     * @param request
     * @param response
     */
    @Override
    public void deleteProductFromCookie(String skuId, HttpServletRequest request, HttpServletResponse response) {
        //首先获取购物车
        String cookie = null;
        try {
            cookie = CookieUtil.getCookie(request, COOKIE_NAME);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //转为list集合
        List<Cart> cartList = JSON.parseArray(cookie, Cart.class);
        //这里使用断言可以消除警告
        assert cartList != null;
        for (Cart cart : cartList) {//从list集合找到元素
            if(skuId.equals(""+cart.getProductSkuId())){
                if(cart.getProductNum() == 1){//数量为1 直接删除
                    cartList.remove(cart);
                }else{//大于1 直接减1
                    cart.setProductNum(cart.getProductNum()-1);
                }
                break;
            }
        }
        //首先删除整个cookie然后重新设置
        CookieUtil.deleteCookie(response,COOKIE_NAME);
        try {
            CookieUtil.setCookie(response,COOKIE_NAME,JSON.toJSONString(cartList));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    /***
     * 直接从redis中删除 不管库存
     * @param userId
     * @param skuId
     */
    @Override
    public void deleteThisProductFromRedis(String userId, String skuId) {
        String key = "user:" + userId + ":cart";
        String cstr = (String) RedisUtil.getKeyFromHash(stringRedisTemplate,key, skuId);
        Cart cart = JSON.parseObject(cstr, Cart.class);
        //删除
        RedisUtil.deleteProduct(stringRedisTemplate,key,skuId);
        //同时删除数据库中的值
        cart.setDeleted(true);
        QueryWrapper<Cart> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id",cart.getUserId());
        queryWrapper.eq("product_sku_id",cart.getProductSkuId());
        int rows = cartMapper.update(cart,queryWrapper);
        if(rows == 1){
            log.info(cart.getId()+"删除成功");
        }else{
            log.info(cart.getId()+"删除失败");
        }
    }

    /***
     * 直接删除 不管库存
     * @param skuId
     */
    @Override
    public void deleteThisProductFromCookie(String skuId, HttpServletRequest request, HttpServletResponse response) {
        //首先获取购物车
        String cookie = null;
        try {
            cookie = CookieUtil.getCookie(request, COOKIE_NAME);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        //转为list集合
        List<Cart> cartList = JSON.parseArray(cookie, Cart.class);
        //这里使用断言可以消除警告
        assert cartList != null;
        for (Cart cart : cartList) {//从list集合找到元素
            if(skuId.equals(""+cart.getProductSkuId())){
                cartList.remove(cart);
                break;
            }
        }
        //首先删除整个cookie然后重新设置
        CookieUtil.deleteCookie(response,COOKIE_NAME);
        try {
            CookieUtil.setCookie(response,COOKIE_NAME,JSON.toJSONString(cartList));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
}